package cndw.core.dispatch;

import java.lang.reflect.Method;

import cndw.core.dispatch.annotation.Action;
import cndw.core.dispatch.exception.ActionInvokeException;
import cndw.core.util.annotation.NotNull;

/**
 * Action持有类
 * 
 * @author zuojie.x
 */
class ActionExecutor {
	private Object actionObj; // 原对象
	private Class<?> actionClass; // 方法所在的class
	private Method action; // 执行方法
	private Class<?>[] paramTypes; // 参数类型数组
	private Action annotation; // 注解
	private String actionDesc;

	ActionExecutor(Object actionObj, Method action) {
		this.actionObj = actionObj;
		this.action = action;
		actionClass = actionObj.getClass();
		paramTypes = action.getParameterTypes();
		annotation = action.getAnnotation(Action.class);
		if (annotation == null)
			annotation = actionObj.getClass().getAnnotation(Action.class);
		actionDesc = ActionExecutor.generalDesc(actionClass.getSimpleName(), action.getName(), paramTypes);
	}

	/**
	 * 执行
	 * 
	 * @return 执行的返回结果
	 */
	public Object execute() {
		Request req = ThreadLocalRequest.get();
		try {
			return action.invoke(actionObj, (Object[]) req.getParams());
		} catch (Exception e) {
			throw new ActionInvokeException(actionObj, action.getName(), req.getParams());
		}
	}
	
	/**
	 * @return 注解Action的id值
	 */
	public int getActionId() {
		return annotation.id();
	}
	
	/**
	 * @return 每个Action的描述,见{@link ActionExecutor#generalDesc(String, String, Class[])}
	 */
	public String getActionDesc() {
		return actionDesc;
	}
	
	/**
	 * 生成描述,例:pecan.core.dispatch.ActionExecutor.generalKey(String,String,Class[])
	 * @param actionClassName
	 * @param actionName
	 * @param params
	 * @return
	 */
	protected static String generalDesc(String actionClassName, String actionName, Object[] params) {
		StringBuilder builder = new StringBuilder(128);
		builder.append(actionClassName).append(".");
		builder.append(actionName).append("(");
		int i = 0;
		for (Object obj : params) {
			if (i ++ > 0)
				builder.append(",");
			builder.append(getObjectSimpleName(obj));
		}
		builder.append(")");
		return builder.toString();
	}
	
	private static String getObjectSimpleName(Object obj) {
		String simpleName = "";
		Class<?> cla = null;
		if (obj instanceof Class<?>)
			cla = (Class<?>) obj;
		else
			cla = obj.getClass();
		if (byte.class.isAssignableFrom(cla))
			simpleName = "Byte";
		else if (short.class.isAssignableFrom(cla))
			simpleName = "Short";
		else if (long.class.isAssignableFrom(cla))
			simpleName = "Long";
		else
			simpleName = cla.getSimpleName();
		
		return simpleName;
	}
	
	/**
	 * @return 获取控制器的Action注释,先获取方法上的注释,如果方法没有注释,那么使用类的注释.
	 */
	@NotNull
	Action getActionAnnotation() {
		return annotation;
	}
	
	@Override
	public String toString() {
		return actionDesc;
	}
}
